﻿#pragma once

#include "TimeSys.h"

namespace ns_Time
{
    class GPSTime : public TimeSys
    {
    public:
        using WeekType = long long;
        using SecondType = double;

    public:
        GPSTime()
        {
        }

        GPSTime(WeekType week, SecondType second)
            : _week(week),
              _second(second)
        {
        }

        SecondCount SecondFromRefTime() const override
        {
            GPSTime *RefTime = GetRefTime();
            return static_cast<SecondCount>((_week - RefTime->_week) * WeekSecond + (_second - RefTime->_second));
        }

        GPSTime *TimeAfterSecond(SecondCount seconds) const override
        {
            int secondsInt;
            double secondsMilli;
            Mathf::SplitDouble(seconds, &secondsInt, &secondsMilli);

            WeekType plusWeek = secondsInt / WeekSecond;
            SecondType newSecond = secondsInt % WeekSecond + _second + secondsMilli;

            if (newSecond > (double)WeekSecond)
            {
                newSecond -= WeekSecond;
                plusWeek++;
            }

            GPSTime *ans = new GPSTime(_week + plusWeek, newSecond);
            return ans;
        }

        GPSTime *GetRefTime() const override
        {
            static GPSTime RefTime = GPSTime(-1, DaySecond * 2);
            return &RefTime;
        }

        double GetSecond() const
        {
            return _second;
        }

        bool Decode(const std::string& inJson) override
        {
            Json::Value inValue;
			Json::Reader reader;
			bool parsingSuccessful = reader.parse(inJson, inValue);
			if (!(parsingSuccessful && inValue["Type"].asString() == "TimeSys"))
				return false;

            SecondCount seconds = inValue["SecondsFromRefTime"].asDouble();

            auto tmp = GetRefTime()->TimeAfterSecond(seconds);
            *this = *tmp;

            return true;
        }

    private:
        WeekType _week;
        SecondType _second;
    };
}